#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>

//全局变量
int high, width;//游戏画面尺寸
int ball_x, ball_y;//小球的坐标
int ball_vx, ball_vy;//小球的速度
int position_x, position_y;//挡板的中心坐标
int radius;//挡板半径
int left, right;//挡板的左右边界
int ball_number;

void gotoxy(int x, int y)  //光标移动到(x,y)位置
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void HideCursor() // 用于隐藏光标
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };  // 第二个值为0表示隐藏光标
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void startup()
{
	high = 18;
	width = 25;

	ball_x = 1;
	ball_y = width / 2;

	ball_vx = 1;
	ball_vy = 1;

	position_x = high;
	position_y = width / 2;
	radius = 5;
	left = position_y - radius;
	right = position_y + radius;

	ball_number = 0;

	HideCursor();
}

void show()
{
	gotoxy(0,0);
	int i, j;
	for (i = 0; i <= high+1; i++)
	{
		for (j = 0; j <= width; j++)
		{
			if ((i == ball_x) && (j == ball_y))
				printf("o");
			else if (j == width)
				printf("|");//输出右边界
			else if (i == high + 1)
				printf("-");//输出下边界
			else if ((i == high) && (j >= left) && (j <= right))
				printf("*");//输出挡板
			else
				printf(" ");
		}
		printf("\n");
	}
	printf("反弹小球数：%d", ball_number);
}

void updatewithoutinput()
{
	if (ball_x == high-1)
	{
		if ((ball_y >= left) && (ball_y <= right))
		{
			ball_number++;
			ball_vy = -ball_vy;
		}
		else
			printf("Game over!");
		exit(0);
	}

	//根据速度更新小球的位置
	ball_x = ball_x + ball_vx;
	ball_y = ball_y + ball_vy;

	//碰到边界改变小球速度方向，实现反弹
	if ((ball_x == 0) || (ball_y == high-1))
		ball_vx = -ball_vx;
	if ((ball_y == 0) || (ball_y == width-1))
		ball_vy = -ball_vy;

	Sleep(50);

}

void updatewithinput()
{
	char input;
	input = getch();
	if (kbhit())
	{
		if (input = 'a')
		{
			position_y--;
			left = position_y - radius;
			right = position_y + radius;
		}
		if (input = 'd')
		{
			position_y++;
			left = position_y - radius;
			right = position_y + radius;
		}
	}

}

int main()
{
	startup();
	while (1)
	{
		show();
		updatewithoutinput();
		updatewithinput();
	}
	return 0;
}